extends Control
const PCK = preload("res://PCK.gd")
const ResConvert = preload("res://ResConvert.gd")
const GDCReader = preload("res://GDCReader.gd")
#const ByteCode = preload("res://versions/bytecode13.gd")
var curPck
var sha256Key = ""
var convertDirFiles
onready var tree:Tree = $VBox/Tree
onready var fileDialog:FileDialog = $FileDialog
onready var menuFile:MenuButton = $VBox/HBox/MenuFile
onready var menuHelp:MenuButton = $VBox/HBox/MenuHelp
onready var versionOpt:OptionButton = $VBox/OptionButton
onready var progressLabel:Label = $VBox/progress
onready var infoLabel:Label = $VBox/info
onready var encryptionLabel:LineEdit = $VBox/encryption_label
class DirFiles:
	var files:Array
	var curIndex=-1
	var dir:String
	func _init(dir_name):
		dir= dir_name
		files=scan_dir(dir)
	func push_back(child):
		files.push_back(child)
	func size():
		return len(files)
	func next():
		if (curIndex+1)<=len(files)-1:
			curIndex+=1
			return files[curIndex]
		else:
			return null
	func scan_dir(path):
		var file_name
		var files = []
		var dir = Directory.new()
		var error = dir.open(path)
		if error!=OK:
			print("Can't open "+path+"!")
			return
		dir.list_dir_begin(true,true)
		file_name = dir.get_next()
		while file_name!="":
			if dir.current_is_dir():
				var new_path = path+"/"+file_name
				files += scan_dir(new_path)
			else:
				var name = path+"/"+file_name
				files.push_back(name)
			file_name = dir.get_next()
		dir.list_dir_end()
		return files
	func seek(index):
		curIndex=index
	func has_next():
		if len(files)>0:
			return (curIndex+1)<=len(files)-1
		else:
			return false
	
func add_file_to_item(p_item:TreeItem,p_name:String,p_size):
	var pp = p_name.find("/")
	if(pp==-1):
		var item= tree.create_item(p_item)
		item.set_cell_mode(0,TreeItem.CELL_MODE_CHECK)
		item.set_checked(0, true)
		#item.set_editable(0, true)
		item.set_text(0, p_name)
		item.set_text(1,"".humanize_size(p_size))
		item.set_collapsed(true)
	else:
		var dir_name = p_name.substr(0,pp)
		var path= p_name.substr(pp+1,p_name.length())
		var childItem = p_item.get_children()
		while(childItem):
			if childItem.get_text(0) == dir_name:
				add_file_to_item(childItem,path,p_size)
				return
			childItem=childItem.get_next()
		var item = tree.create_item(p_item)
		item.set_cell_mode(0,TreeItem.CELL_MODE_CHECK)
		item.set_checked(0, true)
		#item.set_editable(0, true)
		item.set_text(0, dir_name)
		item.set_collapsed(true)
		add_file_to_item(item,path,p_size)

func _file_select_request(file_path):
	openPckFile(file_path)
	
func _save_dir_select_request(save_path):	
	export_godot_project(save_path)
	
func _convert_file_dir_select_request(select_dir):
	var scriptVersion = versionOpt.get_selected_metadata()
	convertDirFiles = DirFiles.new(select_dir)
		
func openPckFile(pck_path):
	curPck=PCK.new(pck_path)
	curPck.parse()
	infoLabel.text="engine ver:%s pck ver:%s" % [curPck.engine_version,curPck.pck_version]
	tree.clear()
	tree.set_column_titles_visible(true)
	tree.set_column_title(0,"File Name")
	tree.set_column_title(1, "Size")
	var root = tree.create_item()
	root.set_cell_mode(0,TreeItem.CELL_MODE_CHECK)
	root.set_checked(0,true)
	root.set_text(0,"res://")
	root.set_metadata(0,"")
	for file in curPck.files:
		add_file_to_item(root,file.path,file.size)
		
func export_godot_project(savePath):
	if self.curPck:
		self.curPck.decompression(savePath)

func _process(dt):
	if self.curPck:
		var state = self.curPck._process(dt)
		if state==PCK.PCK_STATE.Decompress_Start:
			self.progressLabel.text="decompress %s" % [self.curPck.getProgress()]
		elif state==PCK.PCK_STATE.Decompress_FINSH:
			pass
	if self.convertDirFiles:
		if self.convertDirFiles.has_next():
			self.progressLabel.text="convert %d/%d" % [self.convertDirFiles.curIndex+2,self.convertDirFiles.size()]
			var sha256Key = encryptionLabel.text
			ResConvert.projectConvert(self.convertDirFiles.dir,self.convertDirFiles.next(),versionOpt.get_selected_metadata(),sha256Key)
			

func menu_file_selected(pid):
	if pid==0:
		fileDialog.mode = FileDialog.MODE_OPEN_FILE
		fileDialog.connect("file_selected",self,"_file_select_request")
		fileDialog.add_filter("*.pck")
		fileDialog.popup_centered(Vector2(600,400))
	elif pid==1:
		fileDialog.mode = FileDialog.MODE_OPEN_DIR
		fileDialog.connect("dir_selected",self,"_save_dir_select_request")
		fileDialog.popup_centered(Vector2(600,400))
	elif pid==2:
		fileDialog.mode = FileDialog.MODE_OPEN_DIR
		fileDialog.connect("dir_selected",self,"_convert_file_dir_select_request")
		fileDialog.popup_centered(Vector2(600,400))
		#export_godot_project()
func menu_build_selected(pid):	
	print("pck path:",self.curPck.path)
	var success = ProjectSettings.load_resource_pack(self.curPck.path)
	if success:
		ResConvert.resetProjectSetting("res://project.binary")
		var mainScene= ProjectSettings.get_setting("application/run/main_scene")
		if mainScene:
			print("change scene to ",mainScene)
			get_tree().change_scene(mainScene)
func _getDroppedFilesPath(files:PoolStringArray,screen:int):
	for path in files:
		if path.get_extension()=="pck":
			fileDialog.current_dir=path.get_base_dir()
			openPckFile(path)
			return
func _ready():
	menuHelp.get_popup().add_item("About")
	menuFile.get_popup().add_item("Open")
	menuFile.get_popup().add_item("Decompress")
	menuFile.get_popup().add_item("Convert")
	menuFile.get_popup().connect("id_pressed",self,"menu_file_selected")
	$VBox/HBox/MenuBuild.get_popup().add_item("Run")
	$VBox/HBox/MenuBuild.get_popup().connect("id_pressed",self,"menu_build_selected")	
	for i in range(len(GDCReader.GDScriptDecompVersion)):
		var script_ver = GDCReader.GDScriptDecompVersion[i]
		versionOpt.add_item(script_ver[1],i)
		versionOpt.set_item_metadata(i,script_ver[0])
	versionOpt.select(2)
	get_tree().connect("files_dropped",self,"_getDroppedFilesPath")
	
#	_convert_file_dir_select_request("/Users/qiuleiwang/Documents/test/Resources")
#	var reader = GDCReader.new("res://dump/Data/Enemies/DarkCrawler/DarkCrawler.gdc")
#	reader.format(ByteCode.func_names,ByteCode.Token)
	#ResConvert.importToFile("/Users/qiuleiwang/Downloads/Turing.Complete.Early.Access","/Users/qiuleiwang/Downloads/Turing.Complete.Early.Access/atlas/And3.png.import")
	pass # Replace with function body.


# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
#	pass
